#pragma once
#include "net.hpp"
#include "message.hpp"


/**
 * 消息处理分发模块
 * 根据mtype进行映射 
 */

namespace Json_rpc{

    class Callback{
    public:
        using ptr = std::shared_ptr<Callback>;
        virtual void onMessage(const BaseConnection::ptr &conn , BaseMessage::ptr &msg)=0;
        
    };
    template<typename T>
    class CallbackT : public Callback
    {
    public:
        using ptr = std::shared_ptr<CallbackT<T>>;
        using MessageCallback = std::function<void (const BaseConnection::ptr &conn,std::shared_ptr<T> &msg)>;
        CallbackT(const MessageCallback &handler):_handler(handler){}
        void onMessage(const BaseConnection::ptr &conn , BaseMessage::ptr &msg) override
        {
            auto type_msg = std::dynamic_pointer_cast<T> (msg);
            _handler(conn,type_msg);
        }
    private:
        MessageCallback _handler;
    };

    
    class Dispatcher
    {
    public:
        using ptr = std::shared_ptr<Dispatcher>;
        template<typename T>
        void registerHandler(MType mtype,const typename CallbackT<T>::MessageCallback &handler)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            auto cb = std::make_shared<CallbackT<T>>(handler);
            _handlers.insert(std::make_pair(mtype,cb));
        }
        void onMessage(const BaseConnection::ptr &conn,BaseMessage::ptr &msg)
        {
            //找到消息对应业务处理函数调用
            std::unique_lock<std::mutex> lock(_mutex);
            auto it =_handlers.find(msg->mtype());
            if(it!=_handlers.end())
            {
                it->second->onMessage(conn,msg);
                return;
            }
            //没有找到指定类型的回调 消息类型是我们设计进行确定的 不可能出现找不到的情况 ， 如果出现可能为恶意请求
            ELOG("收到未知类型的消息！");
            conn->shutdown();
        }
    private:
        std::mutex _mutex;
        std::unordered_map<MType,Callback::ptr> _handlers;
    };
    



}